package com.hp.bon.sgw.wh.mml;

import java.io.UnsupportedEncodingException;
import java.util.List;

import org.dom4j.Element;

import com.hp.bon.sgw.wh.mml.common.MMLConstants;
import com.hp.bon.sgw.wh.mml.common.MMLUtils;
import com.hp.bon.sgw.wh.mml.repositories.PropertyRepository;

public class MMLEncoder {
	
	/*
	 *  eg. "LOGIN:USER=system,PSWD=system   "
	 *  the length MUST length % 4 == 0
	 */	
	public static String buildMMLLoginCommand(String user, String password){

		StringBuilder sbuf = new StringBuilder();
		sbuf.append(MMLConstants.CMD_LOGIN);
		//USER=xx
		sbuf.append(MMLConstants.KEY_USER);
		sbuf.append(MMLConstants.MML_EQUALITY);
		sbuf.append(user);
		sbuf.append(MMLConstants.MML_SEPARATOR);
		//PSWD=xx
		sbuf.append(MMLConstants.KEY_PSWD);
		sbuf.append(MMLConstants.MML_EQUALITY);
		sbuf.append(password);
		
		if(sbuf.length() % 4 == 0){
			return sbuf.toString();
		}
		
		int stuff = 4 - sbuf.length() % 4;		
		for(int index=0; index<stuff; index++){
			sbuf.append(MMLConstants.KEY_BLANK);
		}
		
		return sbuf.toString();
	}
	
	/*
	 *  eg. "LOGOUT: "
	 *  the length MUST length % 4 == 0
	 */
	public static String buildMMLLogoutCommand(String user, String password){
		StringBuilder sbuf = new StringBuilder();
		sbuf.append(MMLConstants.CMD_LOGOUT);		
		if(sbuf.length() % 4 == 0){
			return sbuf.toString();
		}		
		int stuff = 4 - sbuf.length() % 4;		
		for(int index=0; index<stuff; index++){
			sbuf.append(MMLConstants.KEY_BLANK);
		}		
		return sbuf.toString();
	}
	
	/*
	 *  
	 */
	public static String buildMMLLoginPackage(String formattedSessionId, int transactionId, String termIdentity, String mmlCommand) throws UnsupportedEncodingException{
		return MMLEncoder.buildMMLEnterCtrlPackage(
				formattedSessionId, transactionId, termIdentity, mmlCommand, 
				MMLConstants.MML_SESSION_LOGIN, 
				MMLUtils.formatServiceName(PropertyRepository.getMMLLoginSN()),
				PropertyRepository.getMMLLanguage()
				);
	}
	
	/*
	 *  
	 */
	public static String buildMMLLogoutPackage(String formattedSessionId, int transactionId, String termIdentiry, String mmlCommand) throws UnsupportedEncodingException{		
		return MMLEncoder.buildMMLEnterCtrlPackage(
				formattedSessionId, transactionId, termIdentiry, mmlCommand, 
				MMLConstants.MML_SESSION_CONNECTION, 
				MMLUtils.formatServiceName(PropertyRepository.getMMLLoginSN()),
				PropertyRepository.getMMLLanguage()
				);
	}
	
	/*
	 *  build login or logout package
	 */
	public static String buildMMLEnterCtrlPackage(
			String formattedSessionId, int transactionId, String termIdentiry, String mmlCommand,
			String sessionCtrl, String serviceName, String language
			) throws UnsupportedEncodingException{

		StringBuilder sbuf = new StringBuilder();
		//message header
		//sbuf.append(MMLConstants.MML_VERSION);
		sbuf.append(MMLUtils.formatMMLVersion());
		sbuf.append(MMLUtils.formatTermIdentity(termIdentiry));
		sbuf.append(MMLUtils.formatServiceName(serviceName));
		//language
		sbuf.append(MMLUtils.formatLanguage(language));
		//session header
		//sbuf.append(MMLUtils.formatSessionId(sessionId));
		sbuf.append(formattedSessionId);
		sbuf.append(sessionCtrl);
		sbuf.append(MMLConstants.MML_SESSION_RETAIN);
		//transaction header
		sbuf.append(MMLUtils.formatTransactionId(transactionId));
		sbuf.append(MMLConstants.MML_TRANSACTION_BEGIN);
		sbuf.append(MMLConstants.MML_SESSION_RETAIN);
		//增加消息Command
		sbuf.append(mmlCommand);
		//增加校验码
		sbuf.append(MMLUtils.genCheckSummary(sbuf.toString()));
		
		//sbuf前面插入固定头 或 package长度
		sbuf.insert(0, MMLUtils.formatPackageLength(MMLConstants.MML_FIX_LEN, mmlCommand.length()));
		sbuf.insert(0, MMLConstants.MML_START_WORD);
		
		//增加Line结束符号
		sbuf.append("\r\n");
		
		return sbuf.toString();
	}
	
	public static String buildMMLTransactionPackage(
			String formattedSessionId, int transactionId, String termIdentiry, String mmlCommand, 
			String sessionCtrl, String language
			) throws UnsupportedEncodingException{

		StringBuilder sbuf = new StringBuilder();
		//message header
		//sbuf.append(MMLConstants.MML_VERSION);
		sbuf.append(MMLUtils.formatMMLVersion());
		sbuf.append(MMLUtils.formatTermIdentity(termIdentiry));
		sbuf.append(MMLConstants.MML_TRANSACTION_SERVICE_NAME);
		//language
		sbuf.append(MMLUtils.formatLanguage(language));		
		//session header
		sbuf.append(formattedSessionId);
		sbuf.append(sessionCtrl);
		sbuf.append(MMLConstants.MML_SESSION_RETAIN);
		//transaction header
		sbuf.append(MMLUtils.formatTransactionId(transactionId));
		sbuf.append(MMLConstants.MML_TRANSACTION_BEGIN);
		sbuf.append(MMLConstants.MML_SESSION_RETAIN);
		//增加消息Command
		sbuf.append(mmlCommand);
		//增加校验码
		sbuf.append(MMLUtils.genCheckSummary(sbuf.toString()));
		
		//sbuf前面插入固定头 或 package长度
		sbuf.insert(0, MMLUtils.formatPackageLength(MMLConstants.MML_FIX_LEN, mmlCommand.length()));
		sbuf.insert(0, MMLConstants.MML_START_WORD);
		
		//增加Line结束符号
		sbuf.append("\r\n");
		
		return sbuf.toString();
	}
	/*
	 *  start with "RECH EVC PPSUSER:" or "" or "" or ""
	 */
	public static String buildMMLTransactionCommand(String capName, String mmlCommandData){
		StringBuilder sbuf = new StringBuilder();
		sbuf.append(PropertyRepository.getMMLCommandPrefix(capName));
		sbuf.append(mmlCommandData);
		if(sbuf.length()%4==0){
			return sbuf.toString();
		}
		int stuff = 4 - sbuf.length()%4;
		for(int index=0;index<stuff;index++){
			sbuf.append(MMLConstants.KEY_BLANK);
		}
		return sbuf.toString();		
	}
	
	public static String buildMMLTransactionCommandData(Element serviceInformation){
		StringBuilder sbuf = new StringBuilder();
		@SuppressWarnings("unchecked")
		List<Element> elements = serviceInformation.elements();
		for(Element e : elements){
			String value = e.getTextTrim();
			if(value!=null && !value.isEmpty()){
				sbuf.append(e.getName());
				sbuf.append(MMLConstants.MML_EQUALITY);
				sbuf.append(value);
				sbuf.append(MMLConstants.MML_SEPARATOR);				
			}			
		}
		int lastIndex = sbuf.lastIndexOf(MMLConstants.MML_SEPARATOR);
		sbuf.delete(lastIndex, sbuf.length());
		return sbuf.toString();		
	}
	
}
